package com.mybatis.plugins;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.XmlConstants;
import org.mybatis.generator.internal.util.JavaBeansUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author: xuKai
 * @date: 2024/3/6 14:53
 * @description:
 */
public class ExtraXmlFilePlugin extends PluginAdapter {
    Logger log = Logger.getLogger(PluginAdapter.class);
    List<GeneratedJavaFile> answer = new ArrayList<>();
    int i = 0;

    public ExtraXmlFilePlugin() {
        super();

    }

    private static FullyQualifiedJavaType defaultValueType;

    @Override
    public boolean validate(List<String> warnings) {
        String diyValueType = context.getProperty("valueType");
        if (StringUtils.isNotEmpty(diyValueType)) {
            defaultValueType = new FullyQualifiedJavaType(diyValueType);
        }
        return true;
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles() {
        return super.contextGenerateAdditionalJavaFiles();
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        return null;
    }

    @Override
    public List<GeneratedXmlFile> contextGenerateAdditionalXmlFiles() {
        return super.contextGenerateAdditionalXmlFiles();
    }

    @Override
    public List<GeneratedXmlFile> contextGenerateAdditionalXmlFiles(IntrospectedTable introspectedTable) {

        FullyQualifiedTable table = introspectedTable.getFullyQualifiedTable();
        XmlElement baseanswer = new XmlElement("mapper"); //$NON-NLS-1$
        String namespace = introspectedTable.getMyBatis3SqlMapNamespace();
        baseanswer.addAttribute(new Attribute("namespace", //$NON-NLS-1$
                namespace));

        List<GeneratedXmlFile> answer = new ArrayList<GeneratedXmlFile>();
        //KEKE_UPDATE 2018-06-12
        String xmlMergeableDiy = context.getProperty("xmlMergeable");
        boolean xmlMergeable = false;
        if ("true".equalsIgnoreCase(xmlMergeableDiy)) {
            xmlMergeable = true;
        }
        //KEKE_UPDATE 2018-06-12
        Document document = new Document(XmlConstants.MYBATIS3_MAPPER_PUBLIC_ID, XmlConstants.MYBATIS3_MAPPER_SYSTEM_ID);
        document.setRootElement(baseanswer);
        String originXmlName = introspectedTable.getMyBatis3XmlMapperFileName();
        String extraXmlName = originXmlName.replace(".", "Extra.");
        GeneratedXmlFile gxf = new GeneratedXmlFile(document, extraXmlName, introspectedTable.getMyBatis3XmlMapperPackage(),
                context.getSqlMapGeneratorConfiguration().getTargetProject(), xmlMergeable, context.getXmlFormatter());
        answer.add(gxf);

        return answer;
        //        return super.contextGenerateAdditionalXmlFiles(introspectedTable);
    }

    /**
     * 组装枚举类
     */
    protected void assembleEnum(String enumName, TopLevelEnumeration enumFile, JSONObject reemarkJson) {
        enumFile.addJavaDocLine("/**");
        enumFile.addJavaDocLine(" *@Author auto");
        enumFile.addJavaDocLine(" */");

        for (Map.Entry<String, Object> json : reemarkJson.entrySet()) {
            JSONObject columnObject = (JSONObject) json.getValue();
            String enumConstatntValue = "";
            String enumConstatntName = "";
            for (Map.Entry<String, Object> jsonInner : columnObject.entrySet()) {
                enumConstatntValue = jsonInner.getKey().toString();
                enumConstatntName = jsonInner.getValue().toString();
            }
            if ("String".equals(defaultValueType.getShortName())) {
                enumFile.addEnumConstant("/**" + json.getValue() + "*/\r\n" + json.getKey().toUpperCase() + "(\"" + enumConstatntValue + "\",\""
                        + enumConstatntName + "\")");
            } else if ("Integer".equals(defaultValueType.getShortName())) {
                enumFile.addEnumConstant(
                        "/**" + json.getValue() + "*/\r\n" + json.getKey().toUpperCase() + "(" + enumConstatntValue + ",\"" + enumConstatntName + "\")");
            }

        }

        enumFile.addField(new Field("value", defaultValueType));
        enumFile.addField(new Field("name", FullyQualifiedJavaType.getStringInstance()));
        Method method = new Method(enumName);
        method.setConstructor(true);
        Parameter valueParameter = new Parameter(defaultValueType, "value");
        Parameter nameParameter = new Parameter(FullyQualifiedJavaType.getStringInstance(), "name");
        method.addParameter(valueParameter);
        method.addParameter(nameParameter);
        method.addBodyLine("this.value=value;");
        method.addBodyLine("this.name=name;");
//        method.setPrivate(true);
        Method getterMethod = getJavaBeansGetter("value", defaultValueType);
        Method setterMethod = getJavaBeansGetter("name", FullyQualifiedJavaType.getStringInstance());
        enumFile.addMethod(method);
        enumFile.addMethod(getterMethod);
        enumFile.addMethod(setterMethod);

    }

    public static Method getJavaBeansGetter(String property, FullyQualifiedJavaType returnType) {

        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(returnType);
        method.setName(JavaBeansUtil.getGetterMethodName(property, FullyQualifiedJavaType.getStringInstance()));
        //        context.getCommentGenerator().addGetterComment(method, introspectedTable, introspectedColumn);

        StringBuilder sb = new StringBuilder();
        sb.append("return "); //$NON-NLS-1$
        sb.append(property);
        sb.append(';');
        method.addBodyLine(sb.toString());

        return method;
    }

    public static Method getJavaBeansSetter(String property) {

        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName(JavaBeansUtil.getSetterMethodName(property));
        method.addParameter(new Parameter(defaultValueType, property));
        //        context.getCommentGenerator().addSetterComment(method, introspectedTable, introspectedColumn);

        StringBuilder sb = new StringBuilder();
        sb.append("this."); //$NON-NLS-1$
        sb.append(property);
        sb.append(" = "); //$NON-NLS-1$
        sb.append(property);
        sb.append(';');
        method.addBodyLine(sb.toString());

        return method;
    }

}